package com.yungam.imcs.controller.efficiency;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.yungam.common.bean.process.ProductProcess;
import com.yungam.common.bean.process.ProductionProcess;
import com.yungam.common.bean.product.ProductInfo;
import com.yungam.common.bean.product.ProductionProduct;
import com.yungam.common.bean.work_order.WorkOrderProduct;
import com.yungam.common.response.RetDTO;
import com.yungam.common.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Api(tags = "产线整体效率页面接口")
@RestController
@RequestMapping("/line")
public class LineEfficiencyController {

    @Resource
    private ProductInfoService productInfoService;
    @Resource
    private WorkOrderProductService workOrderProductService;
    @Resource
    private ProductProcessService productProcessService;
    @Resource
    private ProductionProcessService productionProcessService;
    @Resource
    private ProductionProductService productionProductService;

    /**
     * 获取今天罐体制作的任务数量, 根据产品获取工序, 生成表头
     * @return
     */
    @ApiOperation("获取表头")
    @GetMapping("/getDayTableHead")
    public RetDTO<?> getDayTableHead() {
        Map<String, Object> ans = Maps.newHashMap(); // 返回值

        // 今日所需要制作的罐号
        List<WorkOrderProduct> all = workOrderProductService.list();
        List<String> hasDone = productionProductService.list(new QueryWrapper<ProductionProduct>().eq("state", 1))
                .stream().map(ProductionProduct::getProductSn).collect(Collectors.toList());
        List<WorkOrderProduct> todoList = all.stream().filter(t -> !hasDone.contains(t.getProductSn()))
                .collect(Collectors.toList());

        // 今日完成的罐号
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String format = df.format(now), start = format + " 00:00:00", end = format + " 23:59:59";
        List<String> todayDone = productionProductService.list(new QueryWrapper<ProductionProduct>()
                .eq("state", 1)
                .between("end_time", start, end)).stream().map(ProductionProduct::getProductSn)
                .collect(Collectors.toList());
        List<WorkOrderProduct> doneList = all.stream().filter(t -> todayDone.contains(t.getProductSn()))
                .collect(Collectors.toList());

        List<WorkOrderProduct> list = Lists.newArrayList();
        list.addAll(doneList);
        list.addAll(todoList);

        if (list.size() == 0) return RetDTO.data(null);

        // 所有的产品号
        List<String> productNos = list.stream().map(WorkOrderProduct::getProductNo).collect(Collectors.toList());
        // 保证工序的顺序, 使用 LinkedHashMap
        Map<String, Map<String, String>> heads = Maps.newHashMap();

        for (String productNo : productNos) {
            // 根据 productNo 查询表头
            List<ProductProcess> processes = productProcessService.list(new QueryWrapper<ProductProcess>()
                    .eq("product_no", productNo).orderByAsc("process_id"));
            Map<String, String> cur = Maps.newLinkedHashMap();
            // 生成表头
            for (ProductProcess process : processes) cur.put(process.getProcessNo(), process.getProcessName());
            heads.put(productNo, cur);
        }

        // 产品信息
        List<ProductInfo> products = productInfoService.list(new QueryWrapper<ProductInfo>().in("product_no", productNos));

        // 组装数据
        ans.put("tableHeads", heads);
        ans.put("products", products);
        return RetDTO.data(ans);
    }

    /* 按产品号, 获取当天的相应罐子所有工序的耗时 */
    @ApiOperation("获取表格数据")
    @GetMapping("/dayEffs")
    public RetDTO<?> getDayEfficiency() {
        // 今日所需要制作的罐号
        List<WorkOrderProduct> all = workOrderProductService.list();
        List<String> hasDone = productionProductService.list(new QueryWrapper<ProductionProduct>().eq("state", 1))
                .stream().map(ProductionProduct::getProductSn).collect(Collectors.toList());
        List<WorkOrderProduct> todoList = all.stream().filter(t -> !hasDone.contains(t.getProductSn()))
                .collect(Collectors.toList());
        // 今日完成的罐号
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String format = df.format(now), start = format + " 00:00:00", end = format + " 23:59:59";
        List<String> todayDone = productionProductService.list(new QueryWrapper<ProductionProduct>()
                        .eq("state", 1)
                        .between("end_time", start, end)).stream().map(ProductionProduct::getProductSn)
                        .collect(Collectors.toList());
        List<WorkOrderProduct> doneList = all.stream().filter(t -> todayDone.contains(t.getProductSn()))
                .collect(Collectors.toList());

        List<WorkOrderProduct> products = Lists.newArrayList();
        products.addAll(doneList);
        products.addAll(todoList);

        List<String> snList = products.stream().map(WorkOrderProduct::getProductSn).collect(Collectors.toList()); // 所有的罐号

        if (snList.size() == 0) return RetDTO.data(null);

        // 建立 罐号 - 产品号映射
        Map<String, String> typeMap = Maps.newHashMap();
        for (WorkOrderProduct wop : products) typeMap.put(wop.getProductSn(), wop.getProductNo());

        // 根据罐号查询各工序耗时信息
        List<ProductionProcess> list = productionProcessService
                                .list(new QueryWrapper<ProductionProcess>().in("product_sn", snList));

        // 计算工序耗时
        List<Map<String, Object>> newList = Lists.newArrayList();

        for (ProductionProcess pp : list) {
            Map<String, Object> item = Maps.newHashMap();
            String cumTime = calculate(pp.getStartTime(), pp.getEndTime());
            item.put("productSn", pp.getProductSn());
            item.put("processNo", pp.getProcessNo());
            item.put("cumTime", cumTime);
            newList.add(item);
        }

        // 整合数据
        Map<String, List<Map<String, Object>>> map = Maps.newHashMap();
        for (Map<String, Object> item : newList) {
            String productSn = String.valueOf(item.get("productSn"));
            List<Map<String, Object>> cur = map.getOrDefault(productSn, Lists.newArrayList());
            cur.add(item);
            map.put(productSn, cur);
        }

        // 按照 productNo 组装 data
        Map<String, List<Map<String, Object>>> tableData = Maps.newHashMap();
        for (String k : map.keySet()) {
            List<Map<String, Object>> maps = map.get(k);
            Map<String, Object> data = Maps.newHashMap();
            data.put("productSn", k);
            for (Map<String, Object> obj : maps) data.put(String.valueOf(obj.get("processNo")), obj.get("cumTime"));
            List<Map<String, Object>> itemList = tableData.getOrDefault(typeMap.get(k), Lists.newArrayList());
            itemList.add(data);
            tableData.put(typeMap.get(k), itemList);
        }

        return RetDTO.data(tableData);
    }

    /* 计算耗时 */
    private String calculate(Date startTime, Date endTime) {
        if (endTime == null) return null; // 工序未完成

        Long start = startTime.getTime(), end = endTime.getTime(), diff = (end - start) / 1000;
        if (diff < 0) return null;  // 开始时间大于结束时间（过站后又重新进站）

        // 转成相应格式 5h4m30s
        long hour, min, seconds;

        hour = diff / (60 * 60);
        diff %= (60 * 60);

        min = diff / 60;
        seconds = diff % 60;

        String str = "";

        if (hour > 0) str += hour + "h";
        str += min + "m";
        str += seconds + "s";

        return str;
    }

}
